﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace PlutoStudio.Domain.UnitOfWork
{
    /// <summary>
    /// 该接口用于处理活动的工作单元。
    /// 该接口无法注入，请使用 <see cref="IUnitOfWorkManager"/> 替代。
    /// </summary>
    public interface IActiveUnitOfWork
    {
        /// <summary>
        /// 当此工作单元成功完成时，会引发此事件。
        /// </summary>
        event EventHandler Completed;

        /// <summary>
        /// 当此工作单元失败时，会引发此事件。
        /// </summary>
        event EventHandler<UnitOfWorkFailedEventArgs> Failed;

        /// <summary>
        /// 当此工作单元被释放时，会引发此事件。
        /// </summary>
        event EventHandler Disposed;

        /// <summary>
        /// Gets if this unit of work is transactional.
        /// </summary>
        UnitOfWorkOptions Options { get; }

        /// <summary>
        /// 该工作单元是否已经被释放？
        /// </summary>
        bool IsDisposed { get; }

        /// <summary>
        /// Gets data filter configurations for this unit of work.
        /// </summary>
        IReadOnlyList<DataFilterConfiguration> Filters { get; }


        /// <summary>
        /// 保存该工作单元的所有更改。
        /// 在需要时可以调用此方法来应用更改。
        /// 请注意，如果此工作单元是事务性的，则如果事务回滚，则保存的更改也将被回滚。
        /// 通常不需要显式调用SaveChanges，
        /// 因为所有更改都会自动保存在工作单元的末尾。
        /// </summary>
        void SaveChanges();

        /// <summary>
        /// 保存该工作单元的所有更改。
        /// 在需要时可以调用此方法来应用更改。
        /// 请注意，如果此工作单元是事务性的，则如果事务回滚，则保存的更改也将被回滚。
        /// 通常不需要显式调用SaveChanges，
        /// 因为所有更改都会自动保存在工作单元的末尾。
        /// </summary>
        Task SaveChangesAsync();

        /// <summary>
        /// Disables one or more data filters.
        /// Does nothing for a filter if it's already disabled. 
        /// Use this method in a using statement to re-enable filters if needed.
        /// </summary>
        /// <param name="filterNames">One or more filter names. <see cref="AbpDataFilters"/> for standard filters.</param>
        /// <returns>A <see cref="IDisposable"/> handle to take back the disable effect.</returns>
        IDisposable DisableFilter(params string[] filterNames);

        /// <summary>
        /// Enables one or more data filters.
        /// Does nothing for a filter if it's already enabled.
        /// Use this method in a using statement to re-disable filters if needed.
        /// </summary>
        /// <param name="filterNames">One or more filter names. <see cref="AbpDataFilters"/> for standard filters.</param>
        /// <returns>A <see cref="IDisposable"/> handle to take back the enable effect.</returns>
        IDisposable EnableFilter(params string[] filterNames);

        /// <summary>
        /// Checks if a filter is enabled or not.
        /// </summary>
        /// <param name="filterName">Name of the filter. <see cref="AbpDataFilters"/> for standard filters.</param>
        bool IsFilterEnabled(string filterName);

        /// <summary>
        /// Sets (overrides) value of a filter parameter.
        /// </summary>
        /// <param name="filterName">Name of the filter</param>
        /// <param name="parameterName">Parameter's name</param>
        /// <param name="value">Value of the parameter to be set</param>
        IDisposable SetFilterParameter(string filterName, string parameterName, object value);


    }
}
